package typejump.objects;

import typejump.AnimationManager;
import typejump.engine.BoundsInfo;
import typejump.engine.CollisionProps;

/**
 * This is the object that takes care of geometry stuff like walls
 * and floors and ceilings.
 * @author g
 *
 */
public class Surface extends Sprite {
	
	public static final int BLOCK_TOP = 1;
	public static final int BLOCK_BOTTOM = 2;
	public static final int BLOCK_LEFT = 4;
	public static final int BLOCK_RIGHT = 8;
	private int blocksFlags = 0xFF; // Set ALL of the flags
	
	public Surface(double x, double y, double w, int flags) {
		this.left(x);
		this.top(y);
		this.width(w);
		this.height(20);
		this.dynamic  = false;
		this.physical = true;
		this.blocksFlags = flags;
		setCollision(CollisionProps.T_GEOM, CollisionProps.T_NONE);
		
		this.putAnimation("brick", AnimationManager.FLOOR_BRICK);
		this.putAnimation("brick2", AnimationManager.FLOOR_BRICK_SQ);
	}
	
	public Surface(double x, double y, double w) {
		this(x, y, w, 0xFF);
	}
	
	public String generateSpawnCommand() {
		return getAnimationName();
	}
	
	public static Surface createObject(String params) {
		Surface surface = new Surface(0, 0, 100);
		if (params != null && params.length() > 0) {
			surface.loopAnimation(params);
			surface.scaleToImage();
		}
		return surface;
	}
	
	/**
	 * Makes it so that this surface will block objects 
	 * coming from the specified direction.
	 * @param flag - some combination of BLOCK_TOP, BLOCK_BOTTOM, BLOCK_LEFT, BLOCK_RIGHT
	 */
	public void setBlock(int flag) {
		blocksFlags |= flag;
	}

	/**
	 * Makes it so that this surface will ignore objects 
	 * coming from the specified direction.
	 * @param flag - some combination of BLOCK_TOP, BLOCK_BOTTOM, BLOCK_LEFT, BLOCK_RIGHT
	 */
	public void clearBlock(int flag) {
		blocksFlags &= ~flag;
	}

	/**
	 * Returns whether this surface will block objects 
	 * coming from the specified direction.
	 * @param flag - some combination of BLOCK_TOP, BLOCK_BOTTOM, BLOCK_LEFT, BLOCK_RIGHT
	 */
	private boolean blocks(int flag) {
		return (blocksFlags & flag) == flag;
	}

	@Override
	public void collide(GameObject other, int pass) {
		if (!other.isMoveable()) return;
		
		BoundsInfo olast = other.last();
		
		if (pass == 1 | pass == 2) {
			if (blocks(BLOCK_TOP)) {
				if (olast.bottom() <= last.top() && other.bottom() >= top()) {
					other.vars().set("push up", 1);
					other.vy(vy());
					other.bottom(top());
					if (other.canFall()) {
						other.groundedOn = this;
					}
					return;
				}
			}
			
			if (blocks(BLOCK_BOTTOM)) {
				if (olast.top() >= last.bottom() && other.top() <= bottom()) {
					other.vars().set("push down", 1);
					other.vy(vy());
					other.top(bottom());
					return;
				}
			}
		}
		
		if (pass == 0) {
			if (blocks(BLOCK_LEFT)) {
				if (olast.right() <= last.left() && other.right() > left()) {
					other.vars().set("push left", 1);
					other.vx(vx());
					other.right(left());
					return;
				}
			}
			
			if (blocks(BLOCK_RIGHT)) {
				if (olast.left() >= last.right() && other.left() < right()) {
					other.vars().set("push right", 1);
					other.vx(vx());
					other.left(right());
					return;
				}
			}
		}
	}

}
